/*
 * Execution listeners
 */

var KisBpmEventListenersCtrl = ['$scope', '$modal', '$timeout', '$translate', function ($scope, $modal, $timeout, $translate) {

  // Config for the modal window
  var opts = {
    template: 'editor-app/configuration/properties/event-listeners-popup.html?version=' + Date.now(),
    scope: $scope
  };

  // Open the dialog
  $modal(opts);
}];

//Need a separate controller for the modal window due to https://github.com/angular-ui/bootstrap/issues/259
// Will be fixed in a newer version of Angular UI
var KisBpmEventListenersPopupCtrl = ['$scope', '$q', '$translate', function ($scope, $q, $translate) {

  // Put json representing form properties on scope
  if ($scope.property.value !== undefined && $scope.property.value !== null
    && $scope.property.value.eventListeners !== undefined
    && $scope.property.value.eventListeners !== null) {

    if ($scope.property.value.eventListeners.constructor == String) {
      $scope.eventListeners = JSON.parse($scope.property.value.eventListeners);
    } else {
      // Note that we clone the json object rather then setting it directly,
      // this to cope with the fact that the user can click the cancel button and no changes should have happened
      $scope.eventListeners = angular.copy($scope.property.value.eventListeners);
    }

  } else {
    $scope.eventListeners = [];
  }

  // Array to contain selected properties (yes - we only can select one, but ng-grid isn't smart enough)
  $scope.selectedListeners = [];
  $scope.translationsRetrieved = false;

  $scope.labels = {};

  var eventPromise = $translate('PROPERTY.EXECUTIONLISTENERS.EVENT');
  var implementationPromise = $translate('PROPERTY.EXECUTIONLISTENERS.FIELDS.IMPLEMENTATION');
  var namePromise = $translate('PROPERTY.EXECUTIONLISTENERS.FIELDS.NAME');

  $q.all([eventPromise, implementationPromise, namePromise]).then(function (results) {
    $scope.labels.eventLabel = results[0];
    $scope.labels.implementationLabel = results[1];
    $scope.labels.nameLabel = results[2];
    $scope.translationsRetrieved = true;

    // Config for grid
    $scope.gridOptions = {
      data: 'eventListeners',
      enableRowReordering: true,
      headerRowHeight: 28,
      multiSelect: false,
      keepLastSelected: false,
      selectedItems: $scope.selectedListeners,
      afterSelectionChange: function (rowItem, event) {

        if ($scope.selectedListeners.length > 0) {
          var fields = $scope.selectedListeners[0].fields;
          if (fields !== undefined && fields !== null) {
            for (var i = 0; i < fields.length; i++) {
              var field = fields[i];
              if (field.stringValue !== undefined && field.stringValue !== '') {
                field.implementation = field.stringValue;
              } else if (field.expression !== undefined && field.expression !== '') {
                field.implementation = field.expression;
              } else if (field.string !== undefined && field.string !== '') {
                field.implementation = field.string;
              }
            }
          }

          if (!$scope.selectedListeners[0].events || $scope.selectedListeners[0].events.length == 0) {
            $scope.selectedListeners[0].events = [{event: ''}];
          }
        }
      },
      columnDefs: [{field: 'event', displayName: $scope.labels.eventLabel},
        {field: 'implementation', displayName: $scope.labels.implementationLabel}]
    };
  });

  // Click handler for + button after enum value
  $scope.addEventValue = function (index) {
    $scope.selectedListeners[0].events.splice(index + 1, 0, {event: ''});
  };

  // Click handler for - button after enum value
  $scope.removeEventValue = function (index) {
    $scope.selectedListeners[0].events.splice(index, 1);
    $scope.listenerDetailsChanged();
  };

  $scope.listenerDetailsChanged = function () {
    var listener = $scope.selectedListeners[0];
    if (listener.events) {
      var eventText = '';
      for (var i = 0; i < listener.events.length; i++) {
        if (i > 0) {
          eventText += ", ";
        }
        eventText += listener.events[i].event;
      }
      $scope.selectedListeners[0].event = eventText;
    }

    if (listener.rethrowEvent) {
      var implementationText = '';
      if (listener.rethrowType && listener.rethrowType.length > 0) {
        if (listener.rethrowType === 'error' && listener.errorcode !== '') {
          implementationText = "Rethrow as error " + listener.errorcode;
        } else if (listener.rethrowType === 'message' && listener.messagename !== '') {
          implementationText = "Rethrow as message " + listener.messagename;
        } else if ((listener.rethrowType === 'signal' || listener.rethrowType === 'globalSignal') && listener.signalname !== '') {
          implementationText = "Rethrow as signal " + listener.signalname;
        }
      }
      $scope.selectedListeners[0].implementation = implementationText;
    } else {
      if ($scope.selectedListeners[0].className !== '') {
        $scope.selectedListeners[0].implementation = $scope.selectedListeners[0].className;
      } else if ($scope.selectedListeners[0].delegateExpression !== '') {
        $scope.selectedListeners[0].implementation = $scope.selectedListeners[0].delegateExpression;
      } else {
        $scope.selectedListeners[0].implementation = '';
      }
    }
  };

  // Click handler for add button
  $scope.addNewListener = function () {
    $scope.eventListeners.push({
      event: '',
      implementation: '',
      className: '',
      delegateExpression: '',
      retrowEvent: false
    });
  };

  // Click handler for remove button
  $scope.removeListener = function () {
    if ($scope.selectedListeners.length > 0) {
      var index = $scope.eventListeners.indexOf($scope.selectedListeners[0]);
      $scope.gridOptions.selectItem(index, false);
      $scope.eventListeners.splice(index, 1);

      $scope.selectedListeners.length = 0;
      if (index < $scope.eventListeners.length) {
        $scope.gridOptions.selectItem(index + 1, true);
      } else if ($scope.eventListeners.length > 0) {
        $scope.gridOptions.selectItem(index - 1, true);
      }
    }
  };

  // Click handler for up button
  $scope.moveListenerUp = function () {
    if ($scope.selectedListeners.length > 0) {
      var index = $scope.eventListeners.indexOf($scope.selectedListeners[0]);
      if (index != 0) { // If it's the first, no moving up of course
        // Reason for funny way of swapping, see https://github.com/angular-ui/ng-grid/issues/272
        var temp = $scope.eventListeners[index];
        $scope.eventListeners.splice(index, 1);
        $timeout(function () {
          $scope.eventListeners.splice(index + -1, 0, temp);
        }, 100);

      }
    }
  };

  // Click handler for down button
  $scope.moveListenerDown = function () {
    if ($scope.selectedListeners.length > 0) {
      var index = $scope.eventListeners.indexOf($scope.selectedListeners[0]);
      if (index != $scope.eventListeners.length - 1) { // If it's the last element, no moving down of course
        // Reason for funny way of swapping, see https://github.com/angular-ui/ng-grid/issues/272
        var temp = $scope.eventListeners[index];
        $scope.eventListeners.splice(index, 1);
        $timeout(function () {
          $scope.eventListeners.splice(index + 1, 0, temp);
        }, 100);

      }
    }
  };

  // Click handler for save button
  $scope.save = function () {

    if ($scope.eventListeners.length > 0) {
      $scope.property.value = {};
      $scope.property.value.eventListeners = $scope.eventListeners;
    } else {
      $scope.property.value = null;
    }

    $scope.updatePropertyInModel($scope.property);
    $scope.close();
  };

  $scope.cancel = function () {
    $scope.property.mode = 'read';
    $scope.$hide();
  };

  // Close button handler
  $scope.close = function () {
    $scope.property.mode = 'read';
    $scope.$hide();
  };

}];
